package com.ybkj.daijia.api.apirest.v4;

import com.ybkj.daijia.serverUtils.HttpClientUtil;
import com.ybkj.daijia.OrderConfirmLocs;
import com.ybkj.daijia.Setting;
import com.ybkj.daijia.serverUtils.SettingUtils;
import com.ybkj.daijia.api.driver.transport.ResultTransport;
import com.ybkj.daijia.api.util.ErrorConstantV4;
import com.ybkj.daijia.common.Pager;
import com.ybkj.daijia.common.Result;
import com.ybkj.daijia.page.Page;
import com.ybkj.daijia.page.impl.PageImpl;
import com.ybkj.daijia.server.errand.Order;
import com.ybkj.daijia.server.errand.Order.PayTypeDetails;
import com.ybkj.daijia.server.errand.OrderType;
import com.ybkj.daijia.server.errand.SelectPrice;
import com.ybkj.daijia.server.event.model.OrderEmployHasPayEvent;
import com.ybkj.daijia.server.event.model.OrderPassengerHasPayEvent;
import com.ybkj.daijia.server.event.model.errand.ErrandMemberRebateEvent;
import com.ybkj.daijia.server.event.model.errand.ErrandOrderCancelEvent;
import com.ybkj.daijia.server.event.model.errand.ErrandOrderConfirmEvent;
import com.ybkj.daijia.server.event.model.errand.ErrandOrderRunEvent;
import com.ybkj.daijia.server.event.model.errand.PaotuiOrderAcceptEvent;
import com.ybkj.daijia.server.mapper.DriverMapper;
import com.ybkj.daijia.server.mc.Enterprise;
import com.ybkj.daijia.server.mc.Passenger;
import com.ybkj.daijia.server.model.Area;
import com.ybkj.daijia.server.model.Company;
import com.ybkj.daijia.server.model.Driver;
import com.ybkj.daijia.server.model.DriverRefuseRecord;
import com.ybkj.daijia.server.model.FirstOrderPassenger;
import com.ybkj.daijia.server.model.OrderLocation;
import com.ybkj.daijia.server.model.OrderLocationMany;
import com.ybkj.daijia.server.sales.Coupon;
import com.ybkj.daijia.server.sales.CouponRule;
import com.ybkj.daijia.server.service.AreaService;
import com.ybkj.daijia.server.service.CompanyService;
import com.ybkj.daijia.server.service.CouponService;
import com.ybkj.daijia.server.service.DriverLoginService;
import com.ybkj.daijia.server.service.DriverRefuseRecordService;
import com.ybkj.daijia.server.service.DriverService;
import com.ybkj.daijia.server.service.ErrandService;
import com.ybkj.daijia.server.service.FirstOrderPassengerService;
import com.ybkj.daijia.server.service.MemberService;
import com.ybkj.daijia.server.service.OrderLocationManyService;
import java.math.BigDecimal;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.event.ApplicationEventMulticaster;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

@Controller("ApiErrandProcessControllerV4")
@RequestMapping(value = "api/errand/v4/")
public class ErrandProcessController {

    private static final Logger logger = LoggerFactory.getLogger(ErrandProcessController.class);

    @Autowired
    private SettingUtils settingUtils;
    @Autowired
    private ErrandService errandService;
    @Autowired
    private MemberService memberService;
    @Autowired
    private AreaService areaService;
    @Autowired
    private CompanyService companyService;
    @Autowired
    private DriverService driverService;
    @Autowired
    private DriverRefuseRecordService driverRefuseRecordService;
    @Autowired
    private CouponService couponService;
    @Autowired
    private OrderLocationManyService orderLocationManyService;
    @Autowired
    private FirstOrderPassengerService firstOrderPassengerService;
    @Autowired
    private ApplicationEventMulticaster applicationEventMulticaster;
    @Autowired
    private DriverMapper driverMapper;
    @Autowired
    private DriverLoginService driverLoginService;

    /**
     * 完成任务调用接口
     *
     * @param orderId
     * @return
     */
    @RequestMapping(value = "completeTaskData", method = RequestMethod.GET)
    public @ResponseBody
    ResultTransport completeTask(Long orderId) {

        logger.error("recv orderId:{}", orderId);

        if (null == orderId) {
            return ResultTransport.getErrorBy(ErrorConstantV4.PARAM_ERROR);
        }

        Order order = errandService.findOne(orderId);

        if (null == order) {
            return ResultTransport.getErrorBy(ErrorConstantV4.ORDER_NOT_EXISTS_ERROR);
        }

        if (!order.getStatus().equals(Order.ORDER_STATUS_ZHIXING)) {
            return ResultTransport.getErrorBy(ErrorConstantV4.ORDER_STATUS_ERROR);
        }

        Driver driver = driverService.findOne(order.getEmployId());
        if (null == driver) {
            return ResultTransport.getErrorBy(ErrorConstantV4.EMPLOY_NOT_EXISTS);
        }
        Passenger passenger = memberService.findOnePassenger(order.getPassengerId());
        if (null == passenger) {
            return ResultTransport.getErrorBy(ErrorConstantV4.PASSENGER_NOT_EXISTS);
        }

        try {
            Map<String, Object> map = new HashMap<String, Object>();
            map.put("orderId", order.getId());
            map.put("orderNumber", order.getOrderNo());
            map.put("orderType", "errand");
            map.put("passengerPhone", passenger.getPhone());
            map.put("passengerName", passenger.getName());
            map.put("passengerType", passenger.getTypeStr());

            // 等级
            map.put("passengerGrade", passenger.getGrade_name());

            Company orderCompany = companyService.findOne(order.getCompanyId());
            map.put("orderCompanyName", orderCompany.getAbbreviation());

            Company passengerCompany = companyService.findOne(passenger.getCompanyId());
            map.put("passengerCompanyName", passengerCompany.getAbbreviation());

            if (passenger.getType() == Passenger.TYPE_PASSENGER) {
                map.put("overdraw", passenger.isAllowOverdraw());
                map.put("virtual",
                    passenger.getDrawMoney().add(passenger.getNodrawMoney())
                        .setScale(2, BigDecimal.ROUND_HALF_UP));
            } else if (passenger.getType() == Passenger.TYPE_ENTERPRISE) {
                Enterprise enterprise = memberService
                    .findOneEnterprise(passenger.getEnterprise_id());
                map.put("overdraw", enterprise.isAllowOverdraw());
                map.put("virtual",
                    enterprise.getDrawMoney().add(enterprise.getNodrawMoney()).setScale(2,
                        BigDecimal.ROUND_HALF_UP));
            }

            // 优惠券
            if (null != order.getCouponId()) {
                Coupon coupon = couponService.findOne(order.getCouponId());
                if (null != coupon) {
                    CouponRule couponRule = coupon.getCouponRule();
                    if (couponRule.getType().equals(CouponRule.TYPE_DEDUCTION)) {
                        map.put("couponMoney", couponRule.getMoney());
                        map.put("coupon_type", CouponRule.TYPE_DEDUCTION);
                    } else if (couponRule.getType().equals(CouponRule.TYPE_DISCOUNT)) {
                        map.put("discount", couponRule.getDiscount());
                        map.put("coupon_type", CouponRule.TYPE_DISCOUNT);
                    }
                }
            }

            // 预先支付
            BigDecimal preyMoney = BigDecimal.ZERO;
            if (order.isIfPayed()) {
                preyMoney = preyMoney.add(new BigDecimal(order.getSignMoney()));
                preyMoney = preyMoney.add(new BigDecimal(order.getBalanceMoney()));
                preyMoney = preyMoney.add(new BigDecimal(order.getAlipayMoney()));
                preyMoney = preyMoney.add(new BigDecimal(order.getWeixinMoney()));
                preyMoney = preyMoney.add(new BigDecimal(order.getUnionpayMoney()));
            }
            map.put("preyMoney", preyMoney.setScale(2, BigDecimal.ROUND_HALF_UP));
            map.put("payed", order.isIfPayed());

            // 首单免费
            Long completeTimes = firstOrderPassengerService.selectAll(passenger.getId(),
                FirstOrderPassenger.FREE_ORDERTYPE_ERRAND);
            if (completeTimes > 0) {
                map.put("firstFree", false);
            } else {
                map.put("firstFree", true);
            }

            map.put("employId", driver.getId());
            map.put("employName", driver.getName());
            map.put("employPhone", driver.getPhone());

            ResultTransport instance = ResultTransport.getErrorBy(ErrorConstantV4.SUCCESS);
            instance.setData(map);
            return instance;

        } catch (Exception e) {
            e.printStackTrace();
            return ResultTransport.getErrorBy(ErrorConstantV4.SERVER_ERROR);
        }
    }

    @RequestMapping(value = "checkTask", method = RequestMethod.GET)
    public @ResponseBody
    ResultTransport checkTask(Long orderId) {

        if (null == orderId) {
            return ResultTransport.getErrorBy(ErrorConstantV4.PARAM_ERROR);
        }

        Order order = errandService.findOne(orderId);

        if (null == order) {
            return ResultTransport.getErrorBy(ErrorConstantV4.ORDER_NOT_EXISTS_ERROR);
        }

        try {

            boolean finished = false;
            if (order.getStatus().equals(Order.ORDER_STATUS_OK)) {
                finished = true;
            }

            ResultTransport instance = ResultTransport.getErrorBy(ErrorConstantV4.SUCCESS);
            instance.setData(finished);
            return instance;

        } catch (Exception e) {
            e.printStackTrace();
            return ResultTransport.getErrorBy(ErrorConstantV4.SERVER_ERROR);
        }
    }

    @RequestMapping(value = "confirmTask", method = RequestMethod.POST)
    public @ResponseBody
    ResultTransport confirmTask(Long orderId, BigDecimal realCash, Double mileage,
        Integer waitedTime, Integer travelTime, BigDecimal guoluMoney, BigDecimal yuanchengMoney,
        BigDecimal otherMoney,
        @RequestParam(required = false, value = "goodsCash") Double goodsCash,
        @RequestParam(required = false, value = "thanksCash") Double thanksCash,
        @RequestParam(required = false, value = "startPrice") BigDecimal startPrice,
        @RequestParam(required = false, value = "mileagePrice") BigDecimal mileagePrice,
        @RequestParam(required = false, value = "runTimePrice") BigDecimal runTimePrice,
        @RequestParam(required = false, value = "waitPrice") BigDecimal waitPrice,
        @RequestParam(required = false, value = "memo") String memo,
        @RequestParam(required = false, value = "jsonLocs") String jsonLocs,
        @RequestParam(required = false, value = "weight") Double weight) {

        return confirmTaskFunction(orderId, realCash, goodsCash, thanksCash, guoluMoney,
            yuanchengMoney, otherMoney,
            mileage, waitedTime, travelTime, startPrice, mileagePrice, runTimePrice, waitPrice,
            memo, null, null,
            jsonLocs, null, weight);
    }

    @RequestMapping(value = "confirmTaskJsonFile", method = RequestMethod.POST)
    public @ResponseBody
    ResultTransport confirmTaskJsonFile(Long orderId, BigDecimal realCash, Double mileage,
        Integer waitedTime, Integer travelTime, BigDecimal guoluMoney, BigDecimal yuanchengMoney,
        BigDecimal otherMoney,
        @RequestParam(required = false, value = "goodsCash") Double goodsCash,
        @RequestParam(required = false, value = "thanksCash") Double thanksCash,
        @RequestParam(required = false, value = "startPrice") BigDecimal startPrice,
        @RequestParam(required = false, value = "mileagePrice") BigDecimal mileagePrice,
        @RequestParam(required = false, value = "runTimePrice") BigDecimal runTimePrice,
        @RequestParam(required = false, value = "waitPrice") BigDecimal waitPrice,
        @RequestParam(required = false, value = "memo") String memo,
        @RequestParam(required = false, value = "justKilometres") Double justKilometres,
        @RequestParam(required = false, value = "justMoney") BigDecimal justMoney,
        @RequestParam(required = false, value = "jsonLocs") String jsonLocs,
        @RequestParam(required = false, value = "jsonLocFile") MultipartFile jsonLocFile
        , @RequestParam(required = false, value = "weight") Double weight) {

        return confirmTaskFunction(orderId, realCash, goodsCash, thanksCash, guoluMoney,
            yuanchengMoney, otherMoney,
            mileage, waitedTime, travelTime, startPrice, mileagePrice, runTimePrice, waitPrice,
            memo,
            justKilometres, justMoney, jsonLocs, jsonLocFile, weight);
    }

    private ResultTransport confirmTaskFunction(Long orderId, BigDecimal realCash, Double goodsCash,
        Double thanksCash,
        BigDecimal guoluMoney, BigDecimal yuanchengMoney, BigDecimal otherMoney, Double mileage,
        Integer waitedTime,
        Integer travelTime, BigDecimal startPrice, BigDecimal mileagePrice, BigDecimal runTimePrice,
        BigDecimal waitPrice, String memo, Double justKilometres, BigDecimal justMoney,
        String jsonLocs,
        MultipartFile jsonLocFile, Double weight) {
        logger.error(
            "recv orderId:{},realCash:{},guoluMoney:{},yuanchengMoney:{},otherMoney:{},startPrice:{},"
                + "mileagePrice:{},runTimePrice:{},waitPrice:{},mileage:{},waitedTime:{},travelTime:{},memo:{}",
            orderId, realCash, guoluMoney, yuanchengMoney, otherMoney, startPrice, mileagePrice,
            runTimePrice,
            waitPrice, mileage, waitedTime, travelTime, memo);

        if (null == orderId || null == realCash || null == mileage || null == waitedTime
            || null == travelTime) {
            return ResultTransport.getErrorBy(ErrorConstantV4.PARAM_ERROR);
        }

        Order order = errandService.findOne(orderId);

        if (null == order) {
            return ResultTransport.getErrorBy(ErrorConstantV4.ORDER_NOT_EXISTS_ERROR);
        }

        if (!order.getStatus().equals(Order.ORDER_STATUS_ZHIXING)) {
            return ResultTransport.getErrorBy(ErrorConstantV4.ORDER_STATUS_ERROR);
        }

        if (order.getTreatment()) {
            ResultTransport instance = ResultTransport.getErrorBy(ErrorConstantV4.SUCCESS);
            instance.setData("waitfinish");
            return instance;
        }

        try {

            BigDecimal hasPayed = BigDecimal.ZERO;// 之前已经实际支付的钱
            if (order.isIfPayed()) {
                hasPayed = hasPayed.add(new BigDecimal(order.getSignMoney()));
                hasPayed = hasPayed.add(new BigDecimal(order.getBalanceMoney()));
                hasPayed = hasPayed.add(new BigDecimal(order.getAlipayMoney()));
                hasPayed = hasPayed.add(new BigDecimal(order.getWeixinMoney()));
                hasPayed = hasPayed.add(new BigDecimal(order.getUnionpayMoney()));
            }

            order.setGuoluMoney(guoluMoney.doubleValue());
            order.setYuanchengMoney(yuanchengMoney.doubleValue());
            order.setOtherMoney(otherMoney.doubleValue());
            order.setRealPay(realCash.doubleValue());
            //获取当前订单是否预付费
            if (order.isIfPayed()) {
                //获取当前收费标准
                Long areaId = order.getAreaId();
                //获取收费标准
                Area one = areaService.findOneWithCharge(areaId);
                //获取订单创建时间
                Date created = order.getCreated();
                SelectPrice selectPrice = new SelectPrice();
                selectPrice.setPrice(0, 0, one, created, Double.parseDouble(order.getWeight()));
                //计算重量费用
                BigDecimal weightPrice = selectPrice.weightPrice;
                //实付金额减去已计算的重量费用信息
                order.setRealPay(realCash.subtract(weightPrice).doubleValue());
            }
            order.setGoodsCash(goodsCash != null ? goodsCash : 0);
            order.setThanksCash(thanksCash != null ? thanksCash : 0);
            order.setWeight(String.valueOf(weight));

            // 优惠券
            Coupon coupon = null;
            BigDecimal coupon_hasPayed = BigDecimal.ZERO;
            Double discount = null;
            if (null != order.getCouponId()) {
                coupon = couponService.findOne(order.getCouponId());
                if (null != coupon) {
                    if (coupon.getCouponRule().getType().equals(CouponRule.TYPE_DEDUCTION)) {
                        coupon_hasPayed = coupon.getCouponRule().getMoney();
                    } else if (coupon.getCouponRule().getType().equals(CouponRule.TYPE_DISCOUNT)) {
                        discount = coupon.getCouponRule().getDiscount();
                        coupon_hasPayed = realCash.subtract(new BigDecimal(order.getGuoluMoney()))
                            .multiply(
                                new BigDecimal(1)
                                    .subtract(new BigDecimal(discount).divide(new BigDecimal(10))))
                            .setScale(0, BigDecimal.ROUND_DOWN);
                    }
                }
            }

            order.setCouponMoney(coupon_hasPayed.doubleValue());
            if (coupon_hasPayed.doubleValue() > 0 && null == order.getPrePayTypeDetail()) {
                order.setPrePayTypeDetail(PayTypeDetails.coupon);
            }
            order.setDiscount(discount);
            order.setTreatment(true);

            order.setStartPrice(startPrice.doubleValue());
            order.setMileagePrice(mileagePrice.doubleValue());
            order.setTravelTimePrice(runTimePrice.doubleValue());
            order.setTravelTime(travelTime);
            order.setMileage(
                new BigDecimal(mileage).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());
            order.setWaitedTime(waitedTime);
            order.setWaitPrice(waitPrice.doubleValue());
            if (null != justKilometres) {
                order.setJustKilometres(justKilometres);
            }
            if (null != justMoney) {
                order.setJustMoney(justMoney);
            }

            Result<Order> result = errandService.confirmTask(order, null, memo);

            Passenger passenger = memberService.findOnePassenger(order.getPassengerId());
            if (StringUtils.isNotBlank(memo)) {
                passenger.setPlateNumber(memo);
                memberService.updatePassenger(passenger);
            }

            if (result.isSuccess()) {
                // 保存位置
                if (null != jsonLocFile) {
                    jsonLocs = OrderConfirmLocs.locs(jsonLocFile);
                }

                if (StringUtils.isNotBlank(jsonLocs)) {
                    OrderLocationMany orderLocationMany = new OrderLocationMany();
                    orderLocationMany.setOrderId(orderId);
                    orderLocationMany.setOrderType(OrderLocation.OrderType.errand);
                    orderLocationMany.setJsonLocs(jsonLocs);
                    orderLocationManyService.save(orderLocationMany);
                }

                BigDecimal money = new BigDecimal(order.getRealPay());// 还需支付的钱
                money = money.subtract(
                    new BigDecimal(order.getGuoluMoney() != null ? order.getGuoluMoney() : 0));
                money = money.subtract(coupon_hasPayed);
                if (money.doubleValue() < 0) {
                    money = BigDecimal.ZERO;
                }
                money = money.subtract(hasPayed);
                money = money
                    .add(new BigDecimal(order.getGuoluMoney() != null ? order.getGuoluMoney() : 0));

                if (!order.isIfPayed()) {
                    if (null != order.getThanksCash() && order.getThanksCash() > 0) {
                        money = money.add(new BigDecimal(order.getThanksCash()));
                    }
                    if (null != order.getGoodsCash() && order.getGoodsCash() > 0) {
                        money = money.add(new BigDecimal(order.getGoodsCash()));
                    }
                }

                if (money.doubleValue() <= 0) {
                    // 直接结算
                    Driver driver = driverService.findOne(order.getEmployId());
                    result = errandService
                        .completeTaskNewV3(order, passenger, driver, "clickComplete", null,
                            hasPayed);

                    if (result.isSuccess()) {
                        OrderEmployHasPayEvent orderEmployHasPayEvent = new OrderEmployHasPayEvent(
                            passenger,
                            order.getId(), "errand");
                        applicationEventMulticaster.multicastEvent(orderEmployHasPayEvent);

                        ErrandMemberRebateEvent memberRebateEvent = new ErrandMemberRebateEvent(
                            passenger, order,
                            new BigDecimal(order.getRealPay()), 1);
                        applicationEventMulticaster.multicastEvent(memberRebateEvent);

                        ResultTransport instance = ResultTransport
                            .getErrorBy(ErrorConstantV4.SUCCESS);
                        instance.setData("hasfinished");
                        return instance;
                    } else {
                        ResultTransport instance = ResultTransport
                            .getErrorBy(ErrorConstantV4.SERVER_ERROR);
                        return instance;
                    }

                } else {
                    // 进入确认页面
                    // 进入确认页面,修改司机在线状态
                    Driver driver = driverService.findOne(order.getEmployId());
                    if (null != driver) {
                        List<Order> activedList = errandService
                            .findActivedOrdersByDriver(driver.getId());
                        if (!CollectionUtils.isEmpty(activedList)) {
                            long pai = 0;
                            long jie = 0;
                            long busy = 0;
                            for (Order activedOrder : activedList) {
                                if (!activedOrder.getId().equals(order.getId())) {
                                    if (activedOrder.getStatus()
                                        .equals(Order.ORDER_STATUS_PAIDAN)) {
                                        ++pai;
                                    } else if (activedOrder.getStatus()
                                        .equals(Order.ORDER_STATUS_JIEDAN)) {
                                        ++jie;
                                    } else if (activedOrder.getStatus()
                                        .equals(Order.ORDER_STATUS_ZHIXING)) {
                                        ++busy;
                                    }
                                }
                            }
                            if (busy > 0 || jie > 0) {
                                driver.setStatus(Driver.DRIVER_BUSY);
                            } else if (pai > 0) {
                                driver.setStatus(Driver.DRIVER_APPLY_ORDER);
                            } else {
                                driver.setStatus(Driver.DRIVER_ONLINE);
                                driver.setJobStatus(null);
                            }
                            driverMapper.updateStatusAndJobStatusByPrimaryKey(driver.getStatus(),
                                driver.getJobStatus(),
                                driver.getId());
                        }
                    }
                    // 客户端提醒付费推送
                    ErrandOrderConfirmEvent errandOrderConfirmEvent = new ErrandOrderConfirmEvent(
                        order);
                    applicationEventMulticaster.multicastEvent(errandOrderConfirmEvent);

                    ResultTransport instance = ResultTransport.getErrorBy(ErrorConstantV4.SUCCESS);
                    instance.setData("waitfinish");
                    return instance;
                }
            } else {
                ResultTransport instance = ResultTransport.getErrorBy(ErrorConstantV4.SERVER_ERROR);
                return instance;
            }
        } catch (Exception e) {
            e.printStackTrace();
            ResultTransport instance = ResultTransport.getErrorBy(ErrorConstantV4.SERVER_ERROR);
            return instance;
        }

    }

    @RequestMapping(value = "finishTask", method = RequestMethod.POST)
    public @ResponseBody
    ResultTransport finishTask(Long orderId, String payType, String who) {

        logger.error("recv orderId:{},payType{}", orderId, payType);

        if (null == orderId || StringUtils.isBlank(payType)) {
            return ResultTransport.getErrorBy(ErrorConstantV4.PARAM_ERROR);
        }

        if (!"helppay".equals(payType) && !"sign".equals(payType) && !"balance".equals(payType)) {
            return ResultTransport.getErrorBy(ErrorConstantV4.PARAM_ERROR);
        }

        Order order = errandService.findOne(orderId);

        if (null == order) {
            return ResultTransport.getErrorBy(ErrorConstantV4.ORDER_NOT_EXISTS_ERROR);
        }

        if (order.getStatus().equals(Order.ORDER_STATUS_OK)) {
            return ResultTransport.getErrorBy(ErrorConstantV4.ORDER_HAS_BEEN_FINISHED);
        }

        if (!order.getStatus().equals(Order.ORDER_STATUS_ZHIXING)) {
            return ResultTransport.getErrorBy(ErrorConstantV4.ORDER_STATUS_ERROR);
        }

        if (!order.getTreatment()) {
            return ResultTransport.getErrorBy(ErrorConstantV4.ORDER_NOT_CONFIRM);
        }

        Setting setting = settingUtils.get();

        Double afterPayMoney = 0d;
        if (null != order.getPrePayTypeDetail()) {
            if (order.getPrePayTypeDetail().equals(PayTypeDetails.coupon)) {
                afterPayMoney = order.getRealPay() - order.getCouponMoney().doubleValue();
            } else {
                afterPayMoney = order.getRealPay() - order.getShouldPay();
            }
        } else {
            afterPayMoney = order.getRealPay();
        }

        Driver driver = driverService.findOne(order.getEmployId());
        if ("helppay".equals(payType)) {// 如果是代付，服务人员收到现金，余额减钱
            if (afterPayMoney.doubleValue() >= 10000) {
                return ResultTransport.getErrorBy(ErrorConstantV4.HELP_PAY_MONEY_TOOLARGE);
            }
            if (null == driver) {
                return ResultTransport.getErrorBy(ErrorConstantV4.EMPLOY_NOT_EXISTS);
            }
            if (!setting.isAllowHelppayNe()) {
                if (driver.getVirtual().doubleValue() < (afterPayMoney.doubleValue())) {
                    return ResultTransport.getErrorBy(ErrorConstantV4.EMPLOY_MONEY_NOT_ENOUGH);
                }
            }
        }

        Passenger passenger = memberService.findOnePassenger(order.getPassengerId());
        if (null != passenger) {
            if ("sign".equals(payType)) {// 签单支付
                if (passenger.getType() == Passenger.TYPE_PASSENGER) {
                    if (!passenger.isAllowOverdraw()) {
                        return ResultTransport.getErrorBy(ErrorConstantV4.PASSENGER_NOT_ALLOW_SIGN);
                    }
                } else if (passenger.getType() == Passenger.TYPE_ENTERPRISE) {
                    Enterprise enterprise = memberService
                        .findOneEnterprise(passenger.getEnterprise_id());
                    if (!enterprise.isAllowOverdraw()) {
                        return ResultTransport.getErrorBy(ErrorConstantV4.PASSENGER_NOT_ALLOW_SIGN);
                    }
                }
            } else if ("balance".equals(payType)) {// 余额支付
                if (passenger.getType().equals(Passenger.TYPE_PASSENGER)) {
                    BigDecimal shengyuMoney = BigDecimal.ZERO;
                    shengyuMoney = shengyuMoney.add(passenger.getNodrawMoney());
                    if (passenger.getDrawMoney().doubleValue() > 0) {
                        shengyuMoney = shengyuMoney.add(passenger.getDrawMoney());
                    }
                    if (shengyuMoney.doubleValue() < afterPayMoney) {
                        return ResultTransport
                            .getErrorBy(ErrorConstantV4.PASSENGER_MONEY_NOT_ENOUGH);
                    }
                } else if (passenger.getType().equals(Passenger.TYPE_ENTERPRISE)) {
                    Enterprise enterprise = memberService
                        .findOneEnterprise(passenger.getEnterprise_id());
                    BigDecimal shengyuMoney = BigDecimal.ZERO;
                    shengyuMoney = shengyuMoney.add(enterprise.getNodrawMoney());
                    if (enterprise.getDrawMoney().doubleValue() > 0) {
                        shengyuMoney = shengyuMoney.add(enterprise.getDrawMoney());
                    }
                    if (shengyuMoney.doubleValue() < afterPayMoney) {
                        return ResultTransport
                            .getErrorBy(ErrorConstantV4.PASSENGER_MONEY_NOT_ENOUGH);
                    }
                }
            }
        }

        try {

            Result<Order> result = errandService
                .completeTaskNewV3(order, passenger, driver, "clickPay", payType, null);

            if (result.isSuccess()) {

                if (StringUtils.isNotBlank(who) && who.equals("passenger")) {
                    OrderPassengerHasPayEvent orderPassengerHasPayEvent = new OrderPassengerHasPayEvent(
                        driver,
                        order.getId(), "errand");
                    applicationEventMulticaster.multicastEvent(orderPassengerHasPayEvent);
                } else {
                    OrderEmployHasPayEvent orderEmployHasPayEvent = new OrderEmployHasPayEvent(
                        passenger, order.getId(),
                        "errand");
                    applicationEventMulticaster.multicastEvent(orderEmployHasPayEvent);
                }

                if (null != passenger) {
                    ErrandMemberRebateEvent memberRebateEvent = new ErrandMemberRebateEvent(
                        passenger, order,
                        new BigDecimal(order.getRealPay()), 1);
                    applicationEventMulticaster.multicastEvent(memberRebateEvent);
                }

                ResultTransport instance = ResultTransport.getErrorBy(ErrorConstantV4.SUCCESS);
                return instance;
            } else {
                if (result.getErrorcode()
                    .equals(String.valueOf(ErrorConstantV4.ORDER_HAS_BEEN_FINISHED.getCode()))) {
                    ResultTransport instance = ResultTransport
                        .getErrorBy(ErrorConstantV4.ORDER_HAS_BEEN_FINISHED);
                    return instance;
                } else {
                    ResultTransport instance = ResultTransport
                        .getErrorBy(ErrorConstantV4.SERVER_ERROR);
                    return instance;
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
            ResultTransport instance = ResultTransport.getErrorBy(ErrorConstantV4.SERVER_ERROR);
            return instance;
        }

    }

    @RequestMapping(value = "pushAcceptOrder")
    public @ResponseBody
    ResultTransport pushAcceptOrder(Long employId, Long orderId) {

        if (null == orderId || null == employId) {
            return ResultTransport.getErrorBy(ErrorConstantV4.PARAM_ERROR);
        }

        Driver driver = driverService.findOne(employId);

        if (null == driver) {
            return ResultTransport.getErrorBy(ErrorConstantV4.EMPLOY_NOT_EXISTS);
        }

        Order order = errandService.findOne(orderId);

        if (null == order) {
            return ResultTransport.getErrorBy(ErrorConstantV4.ORDER_NOT_EXISTS_ERROR);
        }

        try {

            driverService
                .updateStatusAndJobStatus(Driver.DRIVER_BUSY, Driver.DRIVER_JOBSTATUS_PAOTUI,
                    order.getEmployId());

            PaotuiOrderAcceptEvent acceptEvent = new PaotuiOrderAcceptEvent(order, driver);
            applicationEventMulticaster.multicastEvent(acceptEvent);

            ResultTransport instance = ResultTransport.getErrorBy(ErrorConstantV4.SUCCESS);
            instance.setData(orderId);

            return instance;

        } catch (Exception e) {
            e.printStackTrace();
            return ResultTransport.getErrorBy(ErrorConstantV4.SERVER_ERROR);
        }
    }

    @RequestMapping(value = "pushRefuseOrder")
    public @ResponseBody
    ResultTransport pushRefuseOrder(Long orderId, Long employId, String content) {

        if (null == orderId || null == employId || StringUtils.isBlank(content)) {
            return ResultTransport.getErrorBy(ErrorConstantV4.PARAM_ERROR);
        }

        Driver driver = driverService.findOne(employId);

        if (null == driver) {
            return ResultTransport.getErrorBy(ErrorConstantV4.EMPLOY_NOT_EXISTS);
        }

        Order order = errandService.findOne(orderId);

        if (null == order) {
            return ResultTransport.getErrorBy(ErrorConstantV4.ORDER_NOT_EXISTS_ERROR);
        }

        try {

            Long amount = errandService.countBusyAmount(driver.getId());
            if (amount == 0) {
                if (driver.getStatus() != Driver.DRIVER_OFFLINE) {
                    driverService
                        .updateStatusAndJobStatus(Driver.DRIVER_ONLINE, null, driver.getId());
                }
            }

            // 拒绝工单记录
            DriverRefuseRecord driverRefuseRecord = new DriverRefuseRecord();
            driverRefuseRecord.setEmployId(driver.getId());
            driverRefuseRecord.setEmployRealName(driver.getRealname());
            driverRefuseRecord.setEmployUserName(driver.getUsername());
            driverRefuseRecord.setEmployPhone(driver.getPhone());
            driverRefuseRecord.setHappend(new Date());
            driverRefuseRecord.setOrderId(order.getId());
            driverRefuseRecord.setOrderNumber(order.getOrderNo());
            driverRefuseRecord.setOrderCompanyId(order.getCompanyId());
            driverRefuseRecord.setMemo(content);
            driverRefuseRecord.setOrderType(DriverRefuseRecord.OrderType.paotui);
            driverRefuseRecordService.save(driverRefuseRecord);

            ResultTransport instance = ResultTransport.getErrorBy(ErrorConstantV4.SUCCESS);
            return instance;

        } catch (Exception e) {
            e.printStackTrace();
            return ResultTransport.getErrorBy(ErrorConstantV4.SERVER_ERROR);
        }
    }

    @RequestMapping(value = "pushCancelOrder")
    public @ResponseBody
    ResultTransport pushCancelOrder(Long orderId) {

        if (null == orderId) {
            return ResultTransport.getErrorBy(ErrorConstantV4.PARAM_ERROR);
        }

        Order order = errandService.findOne(orderId);

        if (null == order) {
            return ResultTransport.getErrorBy(ErrorConstantV4.ORDER_NOT_EXISTS_ERROR);
        }

        Driver driver = driverService.findOne(order.getEmployId());

        if (null == driver) {
            return ResultTransport.getErrorBy(ErrorConstantV4.EMPLOY_NOT_EXISTS);
        }

        try {
            // 销单退款
            errandService.backMoney(orderId);
            Long amount = errandService.countBusyAmount(driver.getId());
            if (amount == 0) {
                if (driver.getStatus() != Driver.DRIVER_OFFLINE) {
                    driverService
                        .updateStatusAndJobStatus(Driver.DRIVER_ONLINE, null, driver.getId());
                }
            }

            ErrandOrderCancelEvent cancelEvent = new ErrandOrderCancelEvent(order, driver,
                "driverCancel");
            applicationEventMulticaster.multicastEvent(cancelEvent);

            ResultTransport instance = ResultTransport.getErrorBy(ErrorConstantV4.SUCCESS);

            return instance;

        } catch (Exception e) {
            return ResultTransport.getErrorBy(ErrorConstantV4.SERVER_ERROR);
        }
    }

    @RequestMapping(value = "pushRunOrder")
    public @ResponseBody
    ResultTransport pushRunOrder(Long orderId) {

        if (null == orderId) {
            return ResultTransport.getErrorBy(ErrorConstantV4.PARAM_ERROR);
        }

        Order order = errandService.findOne(orderId);

        if (null == order) {
            return ResultTransport.getErrorBy(ErrorConstantV4.ORDER_NOT_EXISTS_ERROR);
        }

        Driver driver = driverService.findOne(order.getEmployId());

        if (null == driver) {
            return ResultTransport.getErrorBy(ErrorConstantV4.EMPLOY_NOT_EXISTS);
        }

        Passenger passenger = memberService.findOnePassenger(order.getPassengerId());

        // if(null==passenger){
        // return ResultTransport.getErrorBy(ErrorConstantV4.PASSENGER_NOT_EXISTS);
        // }

        try {

            if (null != passenger) {
                ErrandOrderRunEvent runEvent = new ErrandOrderRunEvent(order, passenger);
                applicationEventMulticaster.multicastEvent(runEvent);
            }

            ResultTransport instance = ResultTransport.getErrorBy(ErrorConstantV4.SUCCESS);

            return instance;

        } catch (Exception e) {
            return ResultTransport.getErrorBy(ErrorConstantV4.SERVER_ERROR);
        }
    }

    // v4补单预算费用（创建订单）
    @RequestMapping(value = "getPriceByAreaId")
    public @ResponseBody
    ResultTransport getPriceByAreaId(@RequestParam(required = true, value = "areaId") Long areaId,
        @RequestParam(required = true, value = "startLat") Double startLat,
        @RequestParam(required = true, value = "startLng") Double startLng,
        @RequestParam(required = false, value = "endLat") Double endLat,
        @RequestParam(required = false, value = "endLng") Double endLng,
        @RequestParam(required = false, value = "weight") Double weight) {

        if (null == areaId || null == startLat || null == startLng) {
            return ResultTransport.getErrorBy(ErrorConstantV4.PARAM_ERROR);
        }

        try {
            Double mileage = 0.0;
            Integer time = 0;
            if (startLat != null && startLng != null && endLat != null && endLng != null) {
                Result<Map<String, Long>> result = HttpClientUtil
                    .getDistanceAndTimeValueByTwoPoints(startLng, startLat,
                        endLng, endLat);
                Map<String, Long> result2 = result.getResult();
                Long distance = result2.get("distance");// 米
                Long timemis = result2.get("time");// 秒
                time = (int) (timemis / 60);
                mileage = (double) (distance / 1000d);
            }
            Map<String, Object> map2 = errandService
                .getNewPrice(areaId, mileage, time, null, weight);
            if ((Boolean) map2.get("success")) {
                Map<String, Object> data = new HashMap<String, Object>();
                data.put("money", map2.get("money"));
                data.put("mileage", mileage);
                data.put("time", time);
                data.put("startPrice", map2.get("startPrice"));
                data.put("weightPrice", map2.get("weightPrice"));
                data.put("mileagePrice", map2.get("mileagePrice"));
                data.put("travelTimePrice", map2.get("travelTimePrice"));
                data.put("pay_detail", map2.get("pay_detail"));

                ResultTransport instance = ResultTransport.getErrorBy(ErrorConstantV4.SUCCESS);
                instance.setData(data);
                return instance;
            } else {
                return ResultTransport.getErrorBy(ErrorConstantV4.SERVER_ERROR);
            }
        } catch (Exception e) {
            e.printStackTrace();
            return ResultTransport.getErrorBy(ErrorConstantV4.SERVER_ERROR);
        }
    }

    // v4补单预算费用（未创建订单）
    @RequestMapping(value = "getPriceByTimeAndMileage")
    public @ResponseBody
    ResultTransport getPriceByTimeAndMileage(
        @RequestParam(required = true, value = "areaId") Long areaId,
        @RequestParam(required = true, value = "time") Integer time,
        @RequestParam(required = false, value = "weight") Double weight,
        @RequestParam(required = true, value = "mileage") Double mileage) {
        if (null == areaId || null == time || null == mileage) {
            return ResultTransport.getErrorBy(ErrorConstantV4.PARAM_ERROR);
        }
        try {
            Map<String, Object> map2 = errandService
                .getNewPrice(areaId, mileage, time, null, weight);

            if ((Boolean) map2.get("success")) {
                ResultTransport instance = ResultTransport.getErrorBy(ErrorConstantV4.SUCCESS);
                instance.setData(map2.get("money"));
                return instance;
            } else {
                return ResultTransport.getErrorBy(ErrorConstantV4.SERVER_ERROR);
            }
        } catch (Exception e) {
            e.printStackTrace();
            return ResultTransport.getErrorBy(ErrorConstantV4.SERVER_ERROR);
        }
    }

    /**
     * V4确认费用重量预算费用.
     *
     * @param weight
     * @param orderId
     * @return
     */
    @RequestMapping(value = "getErrandWeightPrice", method = RequestMethod.GET)
    public @ResponseBody
    ResultTransport getErrandWeightPrice(
        @RequestParam(required = false, value = "weight") Double weight,
        @RequestParam(required = false, value = "orderId") Long orderId,
        @RequestParam(required = false, value = "time") Long time,
        @RequestParam(required = false, value = "mileage") Double mileage) {
        if (null == orderId) {
            return ResultTransport.getErrorBy(ErrorConstantV4.PARAM_ERROR);
        }
        try {
            Order errand = errandService.findOne(orderId);
            if (null == errand) {
                return ResultTransport.getErrorBy(ErrorConstantV4.ORDER_NOT_EXISTS_ERROR);
            }
            if (null != errand.getCreated() && null != errand.getMileage() && null != errand
                .getAreaId()) {
                Map<String, Object> map2 = errandService
                    .getNewPrice(errand.getAreaId(), mileage, errand.getTravelTime(),
                        null, weight);
                if ((Boolean) map2.get("success")) {
                    ResultTransport instance = ResultTransport.getErrorBy(ErrorConstantV4.SUCCESS);
                    instance.setData(map2);
                    return instance;
                } else {
                    return ResultTransport.getErrorBy(ErrorConstantV4.SERVER_ERROR);
                }
            }
            return ResultTransport.getErrorBy(ErrorConstantV4.ORDER_NOT_EXISTS_ERROR);
        } catch (Exception e) {
            e.printStackTrace();
            return ResultTransport.getErrorBy(ErrorConstantV4.SERVER_ERROR);
        }
    }

    /**
     * 根据跑腿子类型下单
     */
    @RequestMapping(value = "getErrandType", method = RequestMethod.GET)
    public @ResponseBody
    ResultTransport getErrandType(Long errandTypeId) {
        if (null == errandTypeId) {
            return ResultTransport.getErrorBy(ErrorConstantV4.PARAM_ERROR);
        }
        try {
            OrderType orderType = errandService.findByTypeId(errandTypeId);
            ResultTransport instance = ResultTransport.getErrorBy(ErrorConstantV4.SUCCESS);
            instance.setData(orderType);
            return instance;
        } catch (Exception e) {
            e.printStackTrace();
            return ResultTransport.getErrorBy(ErrorConstantV4.SERVER_ERROR);
        }
    }

    /**
     * 根据公司id查询跑腿子类型
     */
    @RequestMapping(value = {"queryType"}, method = RequestMethod.GET)
    public ResultTransport queryType(@RequestParam("companyId") Long companyId,
        @RequestParam("appKey") String appKey) {
        Setting setting = settingUtils.get();
        List<OrderType> orderTypeList = errandService.queryTypeV4(companyId, appKey);
        if (null != orderTypeList && orderTypeList.size() > 0) {
            for (int i = 0; i < orderTypeList.size(); i++) {
                orderTypeList.get(i)
                    .setTypepicture(setting.getWebUrl() + orderTypeList.get(i).getTypepicture());
            }
        }
        ResultTransport instance = ResultTransport.getErrorBy(ErrorConstantV4.SUCCESS);
        instance.setData(orderTypeList);
        return instance;
    }

    @RequestMapping(value = "list", method = RequestMethod.POST)
    @ResponseBody
    public ResultTransport list(@RequestParam(required = false, value = "companyId") Long companyId,
        @RequestParam(required = false, value = "param") String param,
        @RequestParam(required = false, value = "start") String startTime,
        @RequestParam(required = false, value = "orderType") String orderType,
        @RequestParam(required = false, value = "end") String endTime,
        @RequestParam(required = false, value = "page") Integer page,
        @RequestParam(required = false, value = "limit") Integer limit) throws ParseException {

        Date start = null;
        Date end = null;
        if (StringUtils.isNotBlank(startTime)) {
            start = DateUtils.parseDate(startTime, "yyyy-MM-dd");
        }

        if (StringUtils.isNotBlank(endTime)) {
            end = DateUtils.parseDate(endTime, "yyyy-MM-dd");
        }
        Page<Order> orderPage = errandService
            .queryErrandOrder(companyId, start, end, orderType, param, "newOrder",
                "status asc,created desc");
        List<Order> list = orderPage.getContent();
        List<Map<String, Object>> resultList = new ArrayList<>();
        for (Order order : list) {
            Map<String, Object> map = new HashMap<String, Object>();

            map.put("orderId", order.getId());
            map.put("orderNumber", order.getOrderNo());
            if (null != order.getStartTime()) {
                map.put("time", order.getStartTime().getTime());
            } else {
                map.put("time", System.currentTimeMillis());
            }
            String tips = "";
            if (StringUtils.isNotBlank(order.getTips())) {
                if (null != order.getTipsList() && order.getTipsList().size() > 0) {
                    for (int i = 0; i < order.getTipsList().size(); i++) {
                        if (order.getTips().indexOf(order.getTipsList().get(i).getId().toString())
                            != -1) {
                            tips += order.getTipsList().get(i).getTipName() + ",";
                        }
                    }
                }
            }
            if (!StringUtils.isBlank(tips)) {
                tips = tips.substring(0, tips.length() - 1);
            }
            map.put("tips", tips);
            map.put("status", order.getStatus());
            map.put("startLng", order.getStartLng());
            map.put("startLat", order.getStartLat());
            map.put("endLat", order.getDeliverLat());
            map.put("endLng", order.getDeliverLng());
            map.put("fromPlace", order.getStartAddress());
            map.put("fromPlaceDetailed", order.getStartDetailed());
            map.put("toPlace", order.getDeliverAddress());
            map.put("toPlaceDetailed", order.getEndDetailed());

            map.put("orderType", "errand");
            map.put("passengerPhone", order.getPassengerPhone());
            map.put("passengerName", order.getPassengerName());
            map.put("companyAbbreviation", order.getCompanyName());
            StringBuilder builder = new StringBuilder();
            builder.append(order.getContent());
            builder.append("\n");
            if (StringUtils.isNotBlank(order.getStartDetailed())) {
                builder.append("详细起点:" + order.getStartDetailed() + ";\n");
            }
            if (StringUtils.isNotBlank(order.getEndDetailed())) {
                builder.append("详细终点:" + order.getEndDetailed() + ";\n");
            }
            if (StringUtils.isNotBlank(order.getRecipients())) {
                builder.append("收件人:" + order.getRecipients() + ";\n");
            }
            if (StringUtils.isNotBlank(order.getPhone())) {
                builder.append("收件人电话:" + order.getPhone() + ";\n");
            }
            if (StringUtils.isNotBlank(order.getWeight())) {
                builder.append("重量:" + order.getWeight() + ";\n");
            }
            if (StringUtils.isNotBlank(order.getMatter())) {
                builder.append("事项:" + order.getMatter() + ";\n");
            }

            map.put("content", builder.toString());

            map.put("images", order.getImgs());
            map.put("errandType", order.getOrderType());
            Calendar ca = Calendar.getInstance();
            ca.setTime(order.getCreated());
            ca.add(Calendar.HOUR_OF_DAY, 2);
            if (order.getStartTime().getTime() - ca.getTime().getTime() > 0) {
                // 预约时间大于创建时间2小时订单状态为预约订单
                map.put("ifNow", false);
            } else {
                map.put("ifNow", true);
            }
            map.put("errandValuationMethod", order.getErrandValuationMethod());
            map.put("shouldPay",
                new BigDecimal(order.getShouldPay()).setScale(2, BigDecimal.ROUND_HALF_UP));
            map.put("errandserviceType", order.getErrandserviceType());
            map.put("platNo", order.getPlatNo());
            map.put("startDetailed", order.getStartDetailed());
            map.put("endDetailed", order.getEndDetailed());
            map.put("phone", order.getPhone());
            map.put("weight", order.getWeight());
            map.put("content", order.getContent());
            map.put("buyNeeds", order.getBuyNeeds());
            map.put("realPay",
                new BigDecimal(order.getRealPay()).setScale(2, BigDecimal.ROUND_HALF_UP));
            map.put("thanksCash",
                new BigDecimal(order.getThanksCash()).setScale(2, BigDecimal.ROUND_HALF_UP));
            map.put("goodsCash",
                new BigDecimal(order.getGoodsCash()).setScale(2, BigDecimal.ROUND_HALF_UP));
            map.put("addService", order.getAddServices());
            map.put("orderTypeOtherServices", order.getOtherServices());
            map.put("memo", order.getMemoStr());
            map.put("areaId", order.getAreaId());// App上面没有此数据
            Boolean treatment = order.getTreatment();
            map.put("treatment", treatment);
            if (treatment) {
                map.put("realCash", order.getRealPay() != null ? order.getRealPay() : 0.0);
                map.put("guoluMoney", order.getGuoluMoney() != null ? order.getGuoluMoney() : 0.0);
                map.put("yuanchengMoney",
                    order.getYuanchengMoney() != null ? order.getYuanchengMoney() : 0.0);
                map.put("otherMoney", order.getOtherMoney() != null ? order.getOtherMoney() : 0.0);
                map.put("mileage", order.getMileage() != null ? order.getMileage() : 0.0);
                map.put("waitedTime", order.getWaitedTime() != null ? order.getWaitedTime() : 0.0);
                map.put("travelTime", order.getTravelTime() != null ? order.getTravelTime() : 0);
                map.put("startPrice", order.getStartPrice() != null ? order.getStartPrice() : 0.0);
                map.put("mileagePrice",
                    order.getMileagePrice() != null ? order.getMileagePrice() : 0.0);
                map.put("waitPrice", order.getWaitPrice() != null ? order.getWaitPrice() : 0.0);
                map.put("runTimePrice",
                    order.getTravelTimePrice() != null ? order.getTravelTimePrice() : 0.0);
            }
            resultList.add(map);
        }
        Page<Map<String, Object>> mapPage = new PageImpl<Map<String, Object>>(resultList);
        ResultTransport resultTransport = ResultTransport.getErrorBy(ErrorConstantV4.SUCCESS);
        resultTransport.setData(mapPage);
        return resultTransport;

    }
}
